package tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.junit.Before;
import org.junit.Test;

import urbanparks.JobGrade;
/**
 * a test class for the Job Grade class to ensure method correctness.
 * @author Ben Hadorn
 * @version Winter-2012
 */
public class JobGradeTest {
  JobGrade good_grade;
  JobGrade grade_max_0;
  JobGrade increment_users;
  Random make_random = new Random();
  List<String> my_builder = new ArrayList<String>();
  String alphabet = "abcdefghijklmnopqrstuvwxyz";
  /**
   * initilizes the test data before every test.
   */
  @Before
  public void initilizeData() {
    good_grade = new JobGrade("LIGHT", "blah blah", 10);
    increment_users = new JobGrade("MED", "blah blah", 10);
    grade_max_0 = new JobGrade("HARD", "blah blah", 0);
    String tmp;
    for (int i = 0; i < 10; i++) {
      tmp = new String();
      for (int x = 0; i < make_random.nextInt(alphabet.length()); x++) {
        tmp  += (alphabet.charAt(make_random.nextInt(alphabet.length())));
      }
      my_builder.add(tmp);
      good_grade.addUserToGrade(my_builder.get(i).toString());
    }
  }
  /**
   * tests adding a user to the job grade and tests that the max isn't exceeded.
   */
  @Test
  public void testAddUserToGrade() {
    for (int i = 0; i < 10; i++) {
      assertTrue("user not added", increment_users.addUserToGrade(my_builder.get(i).toString()));
    }
      assertFalse("user was added", increment_users.addUserToGrade(my_builder.get(0).toString()));
  }
  /**
   * verify user can't be added to a grade when max = 0.
   */
  @Test
  public void testAddUserToGradeFail() {
    assertFalse("user was added", grade_max_0.addUserToGrade(my_builder.get(0).toString()));
  }
  /**
   * ensures that users can be removed from the job grade list.
   */
  @Test
  public void testRemoveUserFromGrade() {
    int before;
    int after;
    for (int i = 9; i > -1; i--) {
      before = good_grade.getUserList().size();
      good_grade.removeUserFromGrade(my_builder.get(i).toString());
      after = good_grade.getUserList().size();
      assertEquals("user was not removed", before - 1, after);
    }
  }
  /**
   * tests the fail condition when a user is passed into remove 
   * when that user isn't signed.
   */
  @Test
  public void testRemoveNotSignedUserFromGrade() {
    assertFalse("user was removed", good_grade.removeUserFromGrade("not a user"));    
  }
  /**
   * ensures the list returned is the same as the list put in.
   */
  @Test
  public void testGetUserList() {
    assertTrue("lists not equal", my_builder.equals(good_grade.getUserList()));
  }
  /**
   * ensures the correct description is returned.
   */
  @Test
  public void testGetDescription() {
    assertTrue("not the same", "blah blah".equals(good_grade.getDescription()));
  }
  /**
   * tests getter for max needed.
   */
  @Test
  public void testGetMaxNeeded() {
    assertEquals("max not equal", 10, good_grade.getMaxNeeded());
  }
  /**
   * tests that the difficulty is returned by the toString method.
   */
  @Test
  public void testToString() {
    assertEquals("string doesn't match", "LIGHT", good_grade.toString());
  }
  /**
   * tests that the current need is reflected accurately after the user list has been modified.
   */
  @Test
  public void testGetCurrentNeeded() {
    assertEquals("current need incorrect", 0, good_grade.getCurrentNeeded());
    for (int i = 9; i > -1; i--) {
      good_grade.removeUserFromGrade(my_builder.get(i).toString());
      assertEquals("current need not updating", good_grade.getMaxNeeded() - good_grade.getUserList().size(), 
                    good_grade.getCurrentNeeded());
    }
    
  }

}
